﻿

using System;
namespace Pretext
{
    /// <summary>
    /// Represents a single token
    /// </summary>
    public class Token
    {

        public Token() { }

		public Token(TokenType type, string value, int level, int lineNumber, string sourceFile)
			: this(type, value, level) {
			this.LineNumber = lineNumber;
			this.SourceFileDescription = sourceFile;
		}

        public Token(TokenType type, string value, int level)
            : this()
        {
            this.Value = value;
            this.Type = type;
            this.Level = level;
        }

        public Token(TokenType type, string value)
            : this(type, value, 0) { }

        public Token(TokenType type) :
            this(type, string.Empty)
        {
        }

        public string Value { get; set; }
        public TokenType Type { get; set; }
        public int Level { get; set; }
		public int LineNumber { get; set; }
		public string SourceFileDescription { get; set; }

        public bool Is(TokenType type)
        {
            return this.Type == type;
        }

        public bool Is(string value)
        {
            return Value.ToLower() == value.ToLower();
        }

        public bool Is(TokenType type, string value)
        {
            return Is(type) && Is(value);
        }

        public override string ToString()
        {
            return string.Format("{2}: ({1}) \"{0}\"", this.Value, this.Type.ToString(), this.LineNumber);
        }

        public static bool operator ==(Token t1, Token t2)
        {

            if (Object.ReferenceEquals(t1, t2)) return true;
            if (((object)t1 == null) || ((object)t2 == null)) return false;

            return t1.Value == t2.Value && t1.Type == t2.Type;

        }
        public static bool operator !=(Token t1, Token t2)
        {
            return !(t1 == t2);
        }

        public override bool Equals(object obj)
        {

            Token t = obj as Token;
            if ((object)t == null) return false;
            return base.Equals(obj) && t == this;

        }
        public override int GetHashCode()
        {
            return Type.GetHashCode() ^ Value.GetHashCode();
        }

    }
}